package com.xiaoxx.annotation;

import com.xiaoxx.common.base.JwtUser;
import com.xiaoxx.model.entity.sys.SysLog;
import com.xiaoxx.service.SysLogService;
import com.xiaoxx.utils.JwtUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * @author :HX
 * @date : 2023/8/2
 * 日志拦截器
 */
@Aspect
@Component
public class LogRecordsImpl {
    @Resource
    private HttpServletRequest request;

    @Resource
    private SysLogService logService;

    private final List<String> excludeUriList = new ArrayList<>();

    public LogRecordsImpl() {
        // 获取不到用户信息的
        excludeUriList.add("/api/sys/user/register");
        excludeUriList.add("/api/sys/user/login");
        excludeUriList.add("/api/sys/user/gitee/url");
        excludeUriList.add("/api/sys/user/gitee/callback");
        excludeUriList.add("/api/sys/user/user/gitee/callback");
    }

    @Pointcut("@annotation(com.xiaoxx.annotation.LogRecords)")
    public void LogRecordsPointcut() {
    }

    @Around(value = "LogRecordsPointcut()")
    public Object logRecords(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        String ip = getIpAddress(request);                   // 获取用户真实ip(发起者)
        String methodName = request.getRequestURI();                // 请求行中的接口名称
        String method = request.getMethod();                 // 请求方式(get/post)
        String url = request.getRequestURL().toString();     // 获得客户端发送请求的完整url

        SysLog sysLog = new SysLog();
        if (!excludeUriList.contains(methodName)) {
            JwtUser jwtUser = JwtUtil.getJwtUser(request);
            sysLog.setUserId(jwtUser.getUserId());
            sysLog.setFullName(jwtUser.getFullName());
        }
        sysLog.setIp(ip);
        sysLog.setMethodName(methodName);
        sysLog.setMethod(method);
        sysLog.setUrl(url);

        //获取拦截方法名称
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        LogRecords logRecords = methodSignature.getMethod().getDeclaredAnnotation(LogRecords.class);
        sysLog.setModuleName(logRecords.moduleName());
        sysLog.setContent(logRecords.content());
        Object proceed = joinPoint.proceed();
        long endTime = System.currentTimeMillis();
        sysLog.setBusinessTime(endTime - startTime);
        logService.save(sysLog);
        return proceed;
    }


    /**
     * @author HX
     * @create 2022/3/1 14:29
     * @desc 获取ip
     **/
    private String getIpAddress(HttpServletRequest request) {
        String unknown = "unknown";
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
